﻿using System;

namespace xlstool
{
    using NPOI.SS.UserModel;
    public class Excel2003Cell
    {
        internal ICell cell { get;set; }
        internal Excel2003Row row { get; set; }
        internal Excel2003Cell(ICell cell, Excel2003Row row)
        {
            this.cell = cell;
            this.row = row;
        }
        public int CellNo { get { return cell.ColumnIndex + 1; } }
        public string CellName { get { return to_cellname(CellNo); } }
        internal static object readcell_numbervalue(ICell cell)
        {
            // 处理数字类型（可能是整数、浮点数或日期）
            if (DateUtil.IsCellDateFormatted(cell))  // 判断是否为日期格式
            {
                return cell.DateCellValue;  // 日期值（DateTime 类型）
            }
            else
            {
                // 普通数字（可能是整数或小数）
                double numValue = cell.NumericCellValue;
                if (numValue % 1 == 0)  // 整数
                    return (int)numValue;
                else
                    return numValue;  // 浮点数
            }
        }
        public object GetValue()
        {
            switch (cell.CellType)
            {
                case CellType.Blank:
                    return null;  // 空单元格

                case CellType.Boolean:
                    return cell.BooleanCellValue;  // 布尔值

                case CellType.Numeric:
                    return readcell_numbervalue(cell);

                case CellType.String:
                    return cell.StringCellValue;  // 文本值

                case CellType.Formula:
                    switch (cell.CachedFormulaResultType)
                    {
                        case CellType.Blank:
                            return null;  // 空单元格
                        case CellType.Boolean:
                            return cell.BooleanCellValue;  // 布尔值
                        case CellType.Numeric:
                            return readcell_numbervalue(cell);
                        case CellType.String:
                            return cell.StringCellValue;  // 文本值
                        default:
                            return cell.CellFormula;  // 返回公式文本
                    }

                default:
                    return cell.ToString();  // 其他罕见类型（如错误单元格）
            }
        }
        public void SetValue(object value)
        {
            if (value == null)
            {
                cell.SetCellValue(""); // 空值设为空字符串
                return;
            }

            switch (value)
            {
                case string strVal:
                //case string formula when formula.StartsWith("="): // 公式（以 = 开头）
                    cell.SetCellValue(strVal);
                    break;
                case int intVal:
                    cell.SetCellValue(intVal);
                    break;
                case double doubleVal:
                    cell.SetCellValue(doubleVal);
                    break;
                case float floatVal:
                    cell.SetCellValue(floatVal);
                    break;
                case bool boolVal:
                    cell.SetCellValue(boolVal);
                    break;
                case DateTime dateVal:
                    cell.SetCellValue(dateVal); // 自动设置日期格式（需确保单元格样式正确）
                    break;
                default:
                    cell.SetCellValue(value.ToString()); // 其他类型转为字符串
                    break;
            }
        }

        public string Text
        {
            get
            {
                return GetValue()?.ToString() ?? string.Empty;
            }
        }
        public void CopyTo(Excel2003Cell cell)
        {
            cell.cell.CellStyle = this.cell.CellStyle;
            cell.SetValue(this.GetValue());
        }

        internal static string to_cellname(int cellno)
        {
            cellno--;
            var colstack = new Stack<char>();

            var i = cellno % 26;
            colstack.Push(read_abc(i));
            cellno -= i;
            while (cellno > 0)
            {
                cellno /= 26;
                i = cellno % 26;
                colstack.Push(read_abc(i - 1));
                cellno -= i;
            }
            var cellname = string.Empty;
            while (colstack.Count > 0) cellname += colstack.Pop();

            return cellname;
        }
        internal static int to_cellno(string cellname)
        {
            var colno = string.Empty;
            var queue = new Stack<byte>();
            foreach (var c in cellname)
                if (c >= 'a' && c <= 'z') queue.Push((byte)(c - 96));
                else if (c >= 'A' && c <= 'Z') queue.Push((byte)(c - 64));

            var no = 0;
            var base_ = 1;
            while (queue.Count > 0)
            {
                no += base_ * queue.Pop();
                base_ *= 26;
            }
            return no;
        }
        internal static char read_abc(int no)
        {
            return (char)('A' + no);
        }
        public Excel2003Cell NewStyle()
        {
            var style = row.sheet.workbook.CreateStyle();
            style.CloneStyleFrom(Style);
            var font = row.sheet.workbook.CreateFont();
            font.FontName = Font.FontName;
            font.FontHeightInPoints = Font.FontHeightInPoints;
            font.IsBold = Font.IsBold;
            font.IsItalic = Font.IsItalic;
            font.Underline = Font.Underline;
            font.IsStrikeout = Font.IsStrikeout;
            font.Color = Font.Color;
            font.Charset = Font.Charset;
            font.TypeOffset = Font.TypeOffset;
            style.SetFont(font);
            cell.CellStyle = style;
            return this;
        }
        public ICellStyle Style { get { return cell.CellStyle; } set { cell.CellStyle = value; } }
        public IFont Font { get { return row.sheet.workbook.GetFont(cell.CellStyle.FontIndex); } }
        public void SetBold(bool bold = true)
        {
            Font.IsBold = true;
        }
        public void SetFontSize(short fontsize)
        {
            Font.FontHeightInPoints = fontsize;
        }
    }
}
